﻿/*=========================================================================
 * AUTH: Vincent Breton
 * DESC: Align Steering Behavior
 *=========================================================================*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;   //   for Texture2D
using Microsoft.Xna.Framework;  //  for Vector2
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace RisingThreat
{
    class Align
    {
        private float targetOrientation;
        private float targetOrientationToTarget;
        private float timeToTurn = 0.5f;
        public Steering steer;
        private float innerRadius = 10.0f;
        private float outerRadius = 60.0f;

        public Align()
        {
            
        }

        public Steering getSteering(Steering s)
        {
            steer = s;
            AlignHelper();
            return steer;
        }

        public Steering getSteeringToTarget(Steering s, Vector3 target)
        {
            steer = s;
            AlignHelperToTarget(target);
            return steer;
        }

        public void getOrientation()
        {
            if (steer.velocity.Length() > 0)
            {
                targetOrientation = MathHelper.ToDegrees((float)Math.Atan2(steer.velocity.X, steer.velocity.Z));
                return;
            }
            return;
        }

        public void getOrientationToTarget(Vector3 target)
        {
            Vector3 allignVector = target;
            if (allignVector.Length() > 0)
            {
                targetOrientationToTarget = MathHelper.ToDegrees((float)Math.Atan2(allignVector.X, allignVector.Z));
                return;
            }
            return;
        }
        
        public void AlignHelper()
        {
            getOrientation();
            float targetRotation;
            if (targetOrientation == 0.0f)
                return;
            steer.rotation = targetOrientation - steer.orientation;

            if (steer.rotation < -180)
                steer.rotation += 360;
            if (steer.rotation > 180)
                steer.rotation -= 360;

            float rotationSize = Math.Abs(steer.rotation);
            if (rotationSize < innerRadius)
            {
                steer.rotation = 0;
                steer.angularAcceleration = 0;
                return;
            }
            if (rotationSize < outerRadius)
                targetRotation = steer.maxRotation * (rotationSize / outerRadius);
            else
                targetRotation = steer.maxRotation;
            targetRotation *= steer.rotation / rotationSize;
            steer.angularAcceleration = targetRotation - steer.rotation;
            steer.angularAcceleration /= timeToTurn;
            steer.angularAcceleration = Math.Abs(steer.angularAcceleration);
            if (steer.angularAcceleration > steer.maxAngularAcceleration)
            {
                steer.angularAcceleration /= steer.angularAcceleration;
                steer.angularAcceleration *= steer.maxAngularAcceleration;
            }


        }

        public void AlignHelperToTarget(Vector3 target)
        {
            getOrientationToTarget(target);
            float targetRotation;
            if (targetOrientationToTarget == 0.0f)
                return;
            steer.rotation = targetOrientationToTarget - steer.orientation;

            if (steer.rotation < -180)
                steer.rotation += 360;
            if (steer.rotation > 180)
                steer.rotation -= 360;

            float rotationSize = Math.Abs(steer.rotation);
            if (rotationSize < innerRadius)
            {
                steer.rotation = 0;
                steer.angularAcceleration = 0;
                return;
            }
            if (rotationSize < outerRadius)
                targetRotation = steer.maxRotation * (rotationSize / outerRadius);
            else
                targetRotation = steer.maxRotation;
            targetRotation *= steer.rotation / rotationSize;
            steer.angularAcceleration = targetRotation - steer.rotation;
            steer.angularAcceleration /= timeToTurn;
            steer.angularAcceleration = Math.Abs(steer.angularAcceleration);
            if (steer.angularAcceleration > steer.maxAngularAcceleration)
            {
                steer.angularAcceleration /= steer.angularAcceleration;
                steer.angularAcceleration *= steer.maxAngularAcceleration;
            }            
        }
    }
}
